package it.blueocean.acanto.taglibrary.jsp.taglib.tags;

import it.blueocean.acanto.taglibrary.jsp.taglib.tags.container.ContainerStateBean;
import it.blueocean.acanto.taglibrary.jsp.taglib.tags.container.ContainerTag;
import it.blueocean.acanto.taglibrary.jsp.taglib.tags.exceptions.ComponentStateBeanNotFoundException;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.BodyTagSupport;

import org.apache.taglibs.standard.lang.support.ExpressionEvaluatorManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public abstract class AbstractUIComponentTag extends BodyTagSupport
{
	private static final long serialVersionUID = 4960175505099412215L;

	private final static Logger logger_ = LoggerFactory.getLogger(AbstractUIComponentTag.class);

	private String id_;

	private boolean stateful_ = true;

	private String lifeCycle_ = "session";

	private AbstractComponentStateBean stubStateBean_;

	private AbstractComponentStateBean stateBean_;

	public String getId()
	{
		return this.id_;
	}

	public void setId(String paramString)
	{
		this.id_ = paramString;
	}

	public boolean isStatefulComponent()
	{
		return this.stateful_;
	}

	public void setStateful(String paramString)
	{
		if(paramString.equals("false"))
			this.stateful_ = false;
		else
			this.stateful_ = true;
	}

	public AbstractComponentStateBean getStateBean() throws ComponentStateBeanNotFoundException
	{
		if((!(isStatefulComponent())) || (getId() == null))
			return this.stubStateBean_;
		return getScope().getStateBean(getId());
	}

	public void setStateBean(AbstractComponentStateBean paramAbstractComponentStateBean)
	{
		paramAbstractComponentStateBean.setId(getId());
		if((getId() != null) && (isStatefulComponent()))
			getScope().put(getId(), paramAbstractComponentStateBean);
		else
			this.stubStateBean_ = paramAbstractComponentStateBean;
	}

	public boolean isStateInitialized()
	{
		if((!(isStatefulComponent())) || (getId() == null))
			return false;
		if(this.lifeCycle_.equals("page"))
		{
			HttpServletRequest localHttpServletRequest = (HttpServletRequest) this.pageContext.getRequest();
			String str1 = localHttpServletRequest.getServletPath();
			String str2 = localHttpServletRequest.getHeader("referer");
			if(str2 == null)
				return false;
			int i = str2.indexOf(63);
			if(i > 0)
				str2 = str2.substring(0, i);
			if(logger_.isDebugEnabled())
				logger_.debug("current page: " + str1 + " - referrer page: " + str2);
			if(!(str2.endsWith(str1)))
				return false;
		}
		else if(this.lifeCycle_.equals("request"))
		{
			return false;
		}
		return getScope().containsKey(getId());
	}

	public abstract AbstractComponentStateBean initializeState() throws JspException;

	protected void evaluateExpressions() throws Exception
	{
		if(this.id_ == null)
			return;
		this.id_ = ((String) ExpressionEvaluatorManager.evaluate("id", this.id_, String.class, this, this.pageContext));
	}

	public int doAfterBody(AbstractComponentStateBean paramAbstractComponentStateBean) throws JspException
	{
		return super.doAfterBody();
	}

	public int doEndTag(AbstractComponentStateBean paramAbstractComponentStateBean) throws JspException
	{
		return super.doEndTag();
	}

	public void doInitBody(AbstractComponentStateBean paramAbstractComponentStateBean) throws JspException
	{
		super.doInitBody();
	}

	public int doStartTag(AbstractComponentStateBean paramAbstractComponentStateBean) throws JspException
	{
		return super.doStartTag();
	}

	public final int doStartTag() throws JspException
	{
		try
		{
			evaluateExpressions();
		}
		catch (Exception localException)
		{
			throw new JspException(localException);
		}
		if(!(isStateInitialized()))
		{
			this.stateBean_ = initializeState();
			setStateBean(this.stateBean_);
		}
		else
		{
			try
			{
				this.stateBean_ = getStateBean();
			}
			catch (ComponentStateBeanNotFoundException localComponentStateBeanNotFoundException)
			{
				throw new JspException(localComponentStateBeanNotFoundException);
			}
		}
		if(getId() != null)
		{
			ContainerTag localContainerTag = getContainer();
			if(localContainerTag != null)
				localContainerTag.addComponent(this.stateBean_);
			else
				this.pageContext.setAttribute(getId(), this.stateBean_);
		}
		logger_.debug("stateBean_ " + this.stateBean_.getId());
		return doStartTag(this.stateBean_);
	}

	public final int doAfterBody() throws JspException
	{
		return doAfterBody(this.stateBean_);
	}

	public final int doEndTag() throws JspException
	{
		try
		{
			int i = doEndTag(getStateBean());
			return i;
		}
		catch (ComponentStateBeanNotFoundException localComponentStateBeanNotFoundException)
		{
			logger_.error(localComponentStateBeanNotFoundException.getMessage());
			int j = 6;
			return j;
		}
		finally
		{
			releaseState();
		}
	}

	public final void doInitBody() throws JspException
	{
		doInitBody(this.stateBean_);
	}

	public ContainerTag getContainer()
	{
		return ((ContainerTag) findAncestorWithClass(this, ContainerTag.class));
	}

	public StateBeansManager getScope()
	{
		ContainerTag localContainerTag = (ContainerTag) findAncestorWithClass(this, ContainerTag.class);
		if(localContainerTag != null)
			try
			{
				return ((ContainerStateBean) localContainerTag.getStateBean()).getComponents();
			}
			catch (ComponentStateBeanNotFoundException localComponentStateBeanNotFoundException)
			{
				logger_.error(localComponentStateBeanNotFoundException.getMessage());
				return null;
			}
		return StateBeansManager.getInstance(this.pageContext.getSession());
	}

	public String getLocator()
	{
		String str = getId();
		if(str == null)
			return null;
		ContainerTag localContainerTag = getContainer();
		if(localContainerTag != null)
			str = localContainerTag.getLocator().toString() + ".components." + str;
		return str;
	}

	public String getLifeCycle()
	{
		return this.lifeCycle_;
	}

	public void setLifeCycle(String paramString)
	{
		this.lifeCycle_ = paramString;
	}

	protected void releaseState()
	{
		this.stateful_ = true;
		this.lifeCycle_ = "session";
	}

}
